package com.gitee.wsl.jvm.okhttp.intercept.transform


import com.gitee.wsl.jvm.okhttp.OkHttpClientScope
import okhttp3.Interceptor
import okhttp3.MediaType
import okhttp3.MediaType.Companion.toMediaType
import okhttp3.RequestBody.Companion.toRequestBody
import okhttp3.Response
import okhttp3.ResponseBody.Companion.toResponseBody
import okio.Buffer

/**
 * 演示如何加密请求参数/解密响应数据
 */
class EncryptDataInterceptor(val config: EncryptConfig = defaultEncryptConfig) : Interceptor {
    override fun intercept(chain: Interceptor.Chain): Response {
        var request = chain.request()

        // 加密, 仅加密 POST请求/JSON参数类型
        if (request.method == config.method && request.header("Content-Type") == config.mediaType.toString()) {
            val body = request.body
            if (body != null) {
                val buff = Buffer()
                body.writeTo(buff)
                val json = buff.readUtf8()
                if (json.isNotBlank()) {
                    val encryptJson = config.encrypt(json)
                    val newBody = encryptJson.toRequestBody(config.mediaType)
                    request = request.newBuilder().post(newBody).build()
                }
            }
        }

        var response = chain.proceed(request)

        // 解密, 仅解密JSON响应类型
        if (response.header("Content-Type") == config.mediaType.toString()) {
            val body = response.body
            if (body != null) {
                val json = body.string()
                if (json.isNotBlank()) {
                    val decryptJson = config.decode(json)
                    val requestBody = decryptJson.toResponseBody(config.mediaType)
                    response = response.newBuilder().body(requestBody).build()
                }
            }
        }

        return response
    }
}

interface EncryptConfig{
    val method:String
    val mediaType: MediaType
    val encrypt:(body:String)->String
    val decode:(body:String)->String
}

val defaultEncryptConfig = object :EncryptConfig{
    override val method:String = "POST"
    override val mediaType: MediaType = "application/json; charset=utf-8".toMediaType()
    override val encrypt:(body:String)->String = {it}
    override val decode:(body:String)->String = {it}
}

fun OkHttpClientScope.encryptData(config: EncryptConfig){
    getBuilder().addInterceptor(EncryptDataInterceptor(config))
}